import { useQuasar, uid, exportFile } from 'quasar'
import type { QTableColumn } from 'quasar'
import { toValue } from 'vue'
import type { MaybeRefOrGetter } from 'vue'

/**
 * Vue组合式函数,处理QTable的相关功能
 */

export function useTable<T extends Record<string, any>>(
  rows: MaybeRefOrGetter<readonly T[]>,
  columns: MaybeRefOrGetter<QTableColumn[]>,
) {
  const $q = useQuasar()
  /**
   * csv包裹函数
   * @param val
   * @param formatFn
   * @param row
   * @returns
   */
  function wrapCsvValue(val: any, formatFn?: (val: any, row?: T) => any, row?: T): string {
    let formatted = formatFn !== undefined ? formatFn(val, row) : val

    formatted = formatted === undefined || formatted === null ? '' : String(formatted)
    formatted = formatted.split('"').join('""')

    return `"${formatted}"`
  }

  /**
   * 导出方法
   */
  function exportTable(fileName: string) {
    // 使用toValue来获取ref的值, 如果传入的是普通数组也同样使用
    const unrefRows = toValue(rows)
    const unrefCols = toValue(columns)
    if (!unrefRows || unrefRows.length === 0) {
      $q.notify({
        message: '没有可导出的数据',
        color: 'warning',
        icon: 'warning',
        position: 'top',
      })
      return
    }

    const content = [unrefCols.map((col) => wrapCsvValue(col.label))]
      .concat(
        unrefRows.map((row) =>
          unrefCols
            .map((col) => {
              const val =
                typeof col.field === 'function' ? col.field(row) : row[col.field as keyof T]
              return wrapCsvValue(val, col.format, row)
            })
            .join(','),
        ),
      )
      .join('\r\n')

    const status = exportFile(
      `${fileName || 'table-export'}.csv`,
      '\uFEFF' + content,
      'text/csv;charset=utf-8',
    )

    if (status !== true) {
      $q.notify({
        message: '浏览器拒绝了文件下载...',
        color: 'negative',
        icon: 'warning',
      })
    }
  }

  function handelExportTable() {
    $q.dialog({
      title: '导出数据表',
      prompt: {
        model: '',
        type: 'text',
        dense: true,
        placeholder: '请输入文件名',
      },
      ok: '导出',
      cancel: '取消',
      progress: false,
      persistent: true,
    })
      .onOk((data) => {
        exportTable(data || uid())
      })
      .onCancel(() => {
        console.log('用户取消了导出操作')
      })
  }

  /**
   * 筛选列
   */

  return {
    handelExportTable,
  }
}
